'use strict';

const fs = require('fs');
const dayjs = require('dayjs');
const xss = require('xss');
const webConfigData = fs.readFileSync(__dirname + '/../../config/config.system.json');
const webConfig = JSON.parse(webConfigData.toString());
const { getRedisClient } = require('../lib/redis');
const redisClient = getRedisClient();
const emoji = require('../public/home/emoji.json');
const rule = {
  name: {
    required: true,
    type: 'string',
    min: 1,
    max: 6,
  },
  content: {
    required: true,
    type: 'string',
    min: 1,
    max: 50,
  },
};

const Controller = require('egg').Controller;

class HomeController extends Controller {
  // 首页
  async index() {
    const { ctx } = this;
    const currentPage = ctx.request.query.page || 1;
    const start = (currentPage - 1) * 6;
    const end = 6;
    const search = ctx.request.query.search || '';
    const blogs = await ctx.service.home.findAll(search, start, end);
    let num = await ctx.service.home.count();
    const lists = await ctx.service.home.lists();
    num = num[0].num;
    const totalPage = Math.ceil(num / 6);
    for (const item of blogs) {
      item.time = dayjs(item.time * 1000).format('YYYY年MM月DD日 HH:mm:ss');
    }
    await ctx.render('home/index.html', {
      webConfig,
      blogs,
      totalPage,
      currentPage,
      lists,
      search,
    });
  }
  // 热门页
  async hot() {
    const { ctx } = this;
    const lists = await ctx.service.home.lists();
    let hotBlogs = [];
    const HOTBLOGIDARRAY = await redisClient.zrevrange('hotBlogsID', 0, -1);

    if (HOTBLOGIDARRAY?.length) {
      console.info('读取redis缓存');
      for (const hotBlogId of HOTBLOGIDARRAY) {
        const result = await redisClient.hmget(`hotBlogsID:${hotBlogId}`, 'id', 'title', 'click', 'description', 'keywords');
        hotBlogs.push({
          id: result[0],
          title: result[1],
          click: result[2],
          description: result[3],
          keywords: result[4],
        });
      }
    } else {
      console.info('读取mysql');
      hotBlogs = await ctx.service.home.findHotBlogs();
      for (const item of hotBlogs) {
        redisClient.zadd('hotBlogsID', item.click, item.id);
        redisClient.hmset(`hotBlogsID:${item.id}`, item);
        redisClient.expire(`hotBlogsID:${item.id}`, 60 * 60 * 24);
      }
      redisClient.expire('hotBlogsID', 60 * 60 * 24);
    }

    for (const item of hotBlogs) {
      item.time = dayjs(item.time * 1000).format('YYYY年MM月DD日 HH:mm:ss');
    }
    await ctx.render('home/hotArticle.html', {
      webConfig,
      hotBlogs,
      lists,
    });
  }
  // 分类页
  async list() {
    const { ctx } = this;
    const { cid } = ctx.query;
    const lists = await ctx.service.home.lists();
    const blogs = await ctx.service.home.listBlogs(cid);
    blogs.forEach(item => {
      item.time = dayjs(item.time * 1000).format('YYYY年MM月DD日 HH:mm:ss');
    });
    await ctx.render('home/list.html', {
      webConfig,
      lists,
      blogs,
      cid,
    });
  }
  // ajax搜索分类
  async ajaxList() {
    const { ctx } = this;
    const cid = ctx.query.cid;
    const blogs = await ctx.service.home.listBlogs(cid);
    blogs.forEach(item => {
      item.time = dayjs(item.time * 1000).format('YYYY年MM月DD日 HH:mm:ss');
    });
    ctx.ajaxSuccess(blogs);
  }
  // 文章页
  async article() {
    const { ctx } = this;
    const id = ctx.params.id;
    try {
      const queryBlog = ctx.service.home.queryBlog(id);
      const queryList = ctx.service.home.queryList(id);
      const queryComment = ctx.service.home.queryComments(id);
      const queryReply = ctx.service.home.queryReply(id);
      const updateClick = ctx.service.home.updateClick(id);
      const [ blog, list, comments, replies ] = await Promise.all([ queryBlog, queryList, queryComment, queryReply, updateClick ]);
      blog.time = dayjs(blog.time * 1000).format('YYYY年MM月DD日 HH:mm:ss');
      await ctx.render('home/article.html', {
        webConfig,
        blog,
        list,
        comments,
        replies,
        emoji,
      });
    } catch (error) {
      ctx.logger.error(error.message);
      ctx.status = 404;
      await ctx.render('404.html');
    }
  }
  // 处理评论
  async comment() {
    const { ctx } = this;
    ctx.validate(rule);
    const ip = ctx.ip;
    const id = ctx.params.id;
    let { name, content, time, face } = ctx.request.body;
    if (!name || !content || !face) {
      ctx.ajaxFailed('评论失败');
      return false;
    }
    name = xss(name);
    content = xss(content);
    const { affectedRows } = await ctx.service.home.comment({ id, name, content, time, face, ip });
    await ctx.service.home.updateComment(id);
    if (affectedRows !== 1) {
      ctx.ajaxFailed('评论失败');
      return false;
    }
    ctx.ajaxSuccess({
      name,
      content,
      time,
      face,
    });
  }
  // 处理回复
  async reply() {
    const { ctx } = this;
    ctx.validate(rule);
    const ip = ctx.ip;
    const user_id = ctx.request.query.id;
    const blog_id = ctx.request.query.blog_id;
    let { name, content, time, face, reply_name } = ctx.request.body;
    if (!name || !content || !face || !reply_name) {
      ctx.ajaxFailed('评论失败');
      return false;
    }
    name = xss(name);
    content = xss(content);
    const { affectedRows } = await ctx.service.home.replyComment({ user_id, blog_id, name, content, time, face, reply_name, ip });
    await ctx.service.home.updateComment(blog_id);
    if (affectedRows !== 1) {
      ctx.ajaxFailed('回复失败');
      return false;
    }
    ctx.ajaxSuccess({
      name,
      reply_comment: content,
      reply_time: time,
      reply_face: face,
      reply_name,
    });
  }
}

module.exports = HomeController;
